﻿using System;
using System.Collections.Generic;
using System.Linq;
using DosTexPrj.Core.Models;
using DosTexPrj.Core.RepositoriesInterface;
using NUnit.Framework;

namespace DosTexPrj.Implement.NHibernate.Test.Repositories
{
    [TestFixture]
    public class TestCustomerOrder : RepositoryFixtureBase
    {
        private IOrderRepository _orderRepository;
        private IRepository _repository;
        private FabricType _fabricType;
        private PaymentMethod _paymentMethod;
        private Composition _composition;
        private OrderStatus _orderStatus;
        private DeliveryMethod _deliveryMethod;

        protected override void Context()
        {
            this._orderRepository = MyServiceLocator.DoGetInstance<IOrderRepository>();
            this._repository = MyServiceLocator.DoGetInstance<IRepository>();
            this._fabricType = this._repository.FindByKey<FabricType>(1);
            this._deliveryMethod = this._repository.FindByKey<DeliveryMethod>(1);
            this._paymentMethod = this._repository.FindByKey<PaymentMethod>(1);
            this._composition = this._repository.FindByKey<Composition>(1);
            this._orderStatus = this._repository.FindByKey<OrderStatus>(1);
        }

        [Test]
        public void Can_Create_Customer()
        {
            var customer = this.CreateDummyCustomer();
            customer = this._repository.Save<Customer>(customer);
            Assert.IsTrue(customer != null && customer.Id > 0);
        }

        [Test]
        public void Can_Create_New_Customer_Order_OrderDetail()
        {
            var customer = this.CreateDummyCustomer();
            var order = this.CreateDummyOrder(customer);
            var orderDetails = this.CreateDummyOrderDetails(order);
            order.Customer = customer;
            order.OrderDetails = orderDetails;
            customer.Orders.Add(order);
            customer = this._repository.Save<Customer>(customer);
            customer = this._repository.FindByKey<Customer>(customer.Id);
            Assert.IsTrue(customer != null && customer.Id > 0
                            && customer.Orders != null && customer.Orders.Count > 0
                            && customer.Orders[0].OrderDetails != null && customer.Orders[0].OrderDetails.Count > 0);
        }

        [Test]
        public void Can_Create_New_Order_OrderDetail()
        {
            var customer = this.CreateDummyCustomer();
            customer = this._repository.Save<Customer>(customer);

            var order = this.CreateDummyOrder(customer);
            var orderDetails = this.CreateDummyOrderDetails(order);
            order.OrderDetails = orderDetails;

            order = this._orderRepository.Save<Order>(order);
            order = this._orderRepository.FindByKey<Order>(order.Id);
            Assert.IsTrue(order != null && order.Id > 0
                            && order.Customer.Id == customer.Id
                            && order.OrderDetails != null && order.OrderDetails.Count > 0);
        }

        [Test]
        public void Can_Edit_Customer()
        {
            var customer = this.CreateDummyCustomer();
            customer = this._repository.Save<Customer>(customer);
            customer.CustomerName = "EditCustomer";
            customer = this._repository.Save<Customer>(customer);
            Assert.IsTrue(customer != null && customer.CustomerName.Equals("EditCustomer"));
        }

        [Test]
        public void Can_Edit_Order_AddNewDetail()
        {
            var customer = this.CreateDummyCustomer();
            customer = this._repository.Save<Customer>(customer);
            var order = this.CreateDummyOrder(customer);
            var orderDetails = this.CreateDummyOrderDetails(order);
            order.OrderDetails = orderDetails;
            order = this._orderRepository.Save<Order>(order);
            order.IsDeliveredBefore = true;
            order.NumberOfDateExtensionDelivery = 20;
            order.OrderDetails.Add(new OrderDetail
            {
                Color = "Red",
                Composition = _composition,
                CuttableWidth = 300,
                FabricType = _fabricType,
                Weight = 300,
                KgQuantity = 300,
                MtQuantity = 300,
                Price = 300
            });
            order = this._orderRepository.Save<Order>(order);
            Assert.IsTrue(order != null && order.IsDeliveredBefore == true
                            && order.OrderDetails != null && order.OrderDetails.Count == 4);
        }

        [Test]
        public void Can_Delete_Detail_For_Order()
        {
            var customer = this.CreateDummyCustomer();
            customer = this._repository.Save<Customer>(customer);
            var order = this.CreateDummyOrder(customer);
            var orderDetails = this.CreateDummyOrderDetails(order);
            order.OrderDetails = orderDetails;
            order = this._orderRepository.Save<Order>(order);
            this._repository.Delete<OrderDetail>(x => x.Order == order);
            orderDetails = this._repository.FindByCondition<OrderDetail>(x => x.Order == order).ToList();
            Assert.IsTrue(orderDetails == null || orderDetails.Count == 0);
        }

        [Test]
        public void Can_Delete_Order()
        {
            var customer = this.CreateDummyCustomer();
            var order = this.CreateDummyOrder(customer);
            var orderDetails = this.CreateDummyOrderDetails(order);
            order.OrderDetails = orderDetails;
            customer.Orders.Add(order);
            customer = this._repository.Save<Customer>(customer);

            this._repository.Delete<Order>(x => x.Customer == customer);
            order = this._repository.FindByKey<Order>(order.Id);
            Assert.IsNull(order);
        }

        [Test]
        public void Can_Delete_Customer()
        {
            var customer = this.CreateDummyCustomer();
            var order = this.CreateDummyOrder(customer);
            var orderDetails = this.CreateDummyOrderDetails(order);
            order.OrderDetails = orderDetails;
            customer.Orders.Add(order);
            customer = this._repository.Save<Customer>(customer);
            this._repository.Delete<Customer>(x => x.Id == customer.Id);
            customer = this._repository.FindByKey<Customer>(customer.Id);
            Assert.IsNull(customer);
        }

        #region --- private methods ---

        private Order CreateDummyOrder(Customer customer)
        {
            return new Order
            {
                Customer = customer,
                DeliveryDate = DateTime.Today.AddDays(4),
                DeliveryMethod = _deliveryMethod,
                Freight = "Dummy Freight",
                IsDeliveredBefore = false,
                OrderDate = DateTime.Today,
                OrderStatus = _orderStatus,
                PaymentMethod = _paymentMethod
            };
        }

        private IList<OrderDetail> CreateDummyOrderDetails(Order order)
        {
            var orderDetails = new List<OrderDetail>();
            for (int i = 0; i < 3; i++)
            {
                orderDetails.Add(new OrderDetail
                {
                    Color = "blue",
                    Composition = _composition,
                    CuttableWidth = 100,
                    FabricType = _fabricType,
                    Weight = 100,
                    KgQuantity = 100,
                    MtQuantity = 100,
                    Order = order,
                    Price = 1000
                });
            }
            return orderDetails;
        }

        private Customer CreateDummyCustomer()
        {
            return new Customer
            {
                Address = "Dummy Customer Address",
                CustomerName = "Dummy Customer Name",
                PhoneNumber = "123456"
            };
        }

        #endregion --- private methods ---
    }
}